package Comprehensive_02;

import java.util.Arrays;

/**
 * 小和问题：
 *      在一个数组中，每一个数左边比当前数小的数累加起来，叫做这个数组的小和
 *      求一个数组的小和
 *      例如：
 *          [1, 3, 4, 2, 5] 1左边的数比1小，没有；
 *          3左边比3小的数，1；
 *          4左边比4小的数，1、3；
 *          2左边比2小的数，1；
 *          5左边比5小的数，1、3、4、2；
 *          所有小和为 1 + 1 + 3 + 1 + 1 + 3 + 4 + 2 = 16
 */
public class Test8 {
    public static void main(String[] args) {
        int[] arr = new int[]{1, 3, 4, 2, 5};
        System.out.println(process(arr, 0, 4));
        System.out.println(Arrays.toString(arr));
    }
    public static int process(int[] arr, int L, int R){
        if(L >= R){
            return 0;
        }
        int mid = L + ((R - L) >> 1);
        return process(arr, L, mid) + process(arr, mid + 1, R) + merge(arr, L, mid, R);
    }

    private static int merge(int[] arr, int l, int mid, int r) {
        int[] help = new int[r - l + 1];
        int ans = 0;
        int index = 0;
        int p1 = l;
        int p2 = mid + 1;
        while (p1 <= mid && p2 <= r){
            ans += arr[p1] < arr[p2] ? arr[p1] * (r - p2 + 1) : 0;
            help[index++] = arr[p1] < arr[p2] ? arr[p1++] : arr[p2++];
        }
        while (p1 <= mid){
            help[index++] = arr[p1++];
        }
        while (p2 <= r){
            help[index++] = arr[p2++];
        }
        for (int i = 0; i < help.length; i++) {
            arr[l + i] = help[i];
        }
        return ans;
    }
}
